import asyncio
import logging
import sys
import threading
import time

from BinanceSignal.BinanceSignaInit import BinanceSignalInit
from BinanceStrategy.BinanceStrategyTool import get_logger
from BinanceStrategy.BinanceStrategyInit import BinanceStrategyInit
from SqlClass import DbSession
from SqlClass.digiccy_contract_symbol import digiccy_contract_symbol
from SqlClass.digiccy_member import digiccy_member
from SqlClass.digiccy_member_contract_activation import digiccy_member_contract_activation

logging.basicConfig(format='%(asctime)s - %(levelname)s: %(message)s',
                    level=logging.INFO,
                    filename='BinanceQuantify.log',
                    filemode='w+')


def stop(UID):
    session = DbSession()
    session.query(digiccy_member_contract_activation).filter_by(member_id=UID).update("status", 0)
    session.commit()
    session.close()


class BinanceStrategy(BinanceStrategyInit):
    def __init__(self, UID: int, APIKey: str, SecretKey: str, symbol: str):
        super().__init__(UID, APIKey, SecretKey, symbol)
        self.logger.info("开始运行 用户ID:" + str(self.UID))
        self.task_lock = False

        session = DbSession()
        data = session.query(digiccy_member).filter_by(id=self.UID).first()
        self.DMBalance = data.balance
        self.logger.info("用户邮费: " + str(self.DMBalance))
        session.close()

    def _profit_loss(self, pl):
        self.consume(pl)
        pass

    def execute_end(self):
        self.task_lock = False

    def _close_before(self):
        self.logger.info("停止运行")
        stop(self.UID)
        try:
            data = self.account(recvWindow=60000)
            positions = data.get("positions")
            unrealizedProfit = 0
            for var in positions:
                if var.get("symbol") == self.symbol:
                    unrealizedProfit += float(var.get("unrealizedProfit"))
            self.consume(unrealizedProfit)
        except:
            pass

    def consume(self, pl):
        try:
            session = DbSession()
            pl = pl * 0.3
            session.query(digiccy_member).filter_by(id=self.UID).update({"balance": digiccy_member.balance - pl})
            data = session.query(digiccy_member).filter_by(id=self.UID).first()
            self.DMBalance = data.balance
            self.logger.info("用户邮费: " + str(self.DMBalance))
            session.commit()
            session.close()
        except:
            ex_type, ex_val, ex_stack = sys.exc_info()
            self.logger.warning(ex_val)


class BinanceQuantify(BinanceSignalInit):
    def __init__(self, symbol):
        super().__init__(symbol)
        self.user_list = []
        self.task_list = []

    def _score_update(self, score, now_price):  # 分数(或K线)更新执行
        self.task_list = []
        for user in self.user_list:
            if not user.task_lock:  # 添加异步任务
                self.task_list.append(user.execute(score, now_price))
                user.long_stop_loss = self.long_stop_loss
                user.short_stop_loss = self.short_stop_loss
                user.task_lock = True

        if len(self.task_list) > 0:  # 执行异步任务
            threading.Thread(target=self.implement).start()

    def implement(self):
        asyncio.run(asyncio.wait(self.task_list))


def updateUser(SYMBOL):
    session = DbSession()
    dcs = session.query(digiccy_contract_symbol).filter_by(code=SYMBOL.symbol).first()
    dmcas = session.query(digiccy_member_contract_activation).filter_by(symbol_id=dcs.id, status=1).all()
    session.close()
    for dmca in dmcas:
        if dmca.strategy_id == 47 and not user_exist(SYMBOL.user_list, dmca.member_id):  # 如果用户没在执行 添加要执行的用户

            var = BinanceStrategy(UID=dmca.member_id, APIKey=dmca.get_digiccy_member().api_key,
                                  SecretKey=dmca.get_digiccy_member().api_secret, symbol=SYMBOL.symbol)
            SYMBOL.user_list.append(var)

    for user in SYMBOL.user_list:  # 移除取消执行的用户
        if not dmca_exist(dmcas, user.UID) or user.DMBalance <= 0:
            user.close()
            user.clear_orders()
            SYMBOL.user_list.remove(user)


def user_exist(user_list, UID):  # 用户是否在执行
    for user in user_list:
        if user.UID == UID:
            return True
    return False


def dmca_exist(dmcas, UID):  # 用户是否取消执行
    for dmca in dmcas:
        if dmca.member_id == UID:
            return True
    return False


ETCUSDT = BinanceQuantify("ETCUSDT")
while True:
    updateUser(ETCUSDT)
    time.sleep(1)
